#include "header.h"

void *keepAlive(void *ptr)
{
	int sockDesc = (int) ptr;
	
	//printf("KeepAlive Thread created with sockdesc = %d\n", sockDesc);
	
	int keepAliveTimeOut = node.getKeepAliveTimeout();
	while(1)
	{
		sleep(1);												// sleep for 1 sec
		keepAliveTimeOut = keepAliveTimeOut -1;					// decrement the time

		if(shutdownFlag == true || joinToTheNetworkFlag == true)
		{
			//printf("KeepAlive Thread EXIT due to Shutdown\n");
			pthread_exit(NULL);
		}
		
		pthread_mutex_lock(&deleteConnectionLock[sockDesc]);				// if neighbor is not sending keepalive then shutdown
		if(deleteConnection[sockDesc] == true)
		{
			pthread_mutex_unlock(&deleteConnectionLock[sockDesc]);					
			//printf("KeepAlive Thread EXIT at socket = %d\n",sockDesc);
			pthread_exit(NULL);
		}
		pthread_mutex_unlock(&deleteConnectionLock[sockDesc]);					

			
		pthread_mutex_lock(&ResetKeepAlive[sockDesc]);

		if(resetKeepAlive[sockDesc] == true)													// if write got response then this flag will be set and so reset timer
		{
			//printf("Keepalive timeout reset\n");
			keepAliveTimeOut = node.getKeepAliveTimeout();
			resetKeepAlive[sockDesc]=false;
		}
		else if(keepAliveTimeOut == (int)(node.getKeepAliveTimeout()/2))
		{
			Header sendKeepAlive = createHeader(keepAliveMessageType,0);

			Messages keepAliveMsg;
			keepAliveMsg.socketDescripter = sockDesc;
			
			keepAliveMsg.Header = (char*)malloc(28*sizeof(char));
			memset(keepAliveMsg.Header,'\0',28);
			memcpy(&keepAliveMsg.Header[0],&sendKeepAlive.messageType,1);
			memcpy(&keepAliveMsg.Header[1],sendKeepAlive.uoid,20);
			memcpy(&keepAliveMsg.Header[21],&sendKeepAlive.ttl,1);
			memcpy(&keepAliveMsg.Header[22],&sendKeepAlive.reserved,1);
			memcpy(&keepAliveMsg.Header[23],&sendKeepAlive.dataLength,4);
			
			
			struct timeval t;
			gettimeofday(&t, NULL);
			enterLogMessage(keepAliveMsg,'s',t);


			pthread_mutex_lock(&WriteQueue[sockDesc]);
			writeQueue[sockDesc].push_back(keepAliveMsg);			//push to corresponding write queue
			pthread_cond_signal(&condition_var_Write[sockDesc]);	
			pthread_mutex_unlock(&WriteQueue[sockDesc]);
		}
		pthread_mutex_unlock(&ResetKeepAlive[sockDesc]);
	
	}

	return NULL;
}
